2. Field of the Invention
The present invention relates, in general, to software applications, and, more particularly, to a system and method for generating, storing, and using software applications that are represented as data without procedural code.
3. Relevant Background
Although the field of software development is characterized by rapid change, a significant problem leading to the obsolescence of software applications is the inability for an application system itself to change. Software applications offer a set of features, behavior, and user interfaces that define the application. These applications operate on a hardware platform through an operating system adapted specifically to that hardware platform. Typical applications attempt to optimize performance by customizing at least portions of the application code for a particular hardware platform or operating system. These optimizations, however, make the application dependent on the hardware and operating system so that the application must be rewritten in response to hardware and operating system changes.
The conventional approach has been to closely couple a applications to the operating system in an effort to minimize performance and speed. However, by closely binding the application to the operating system, small changes or hardware evolution often require that both the application and the operating system be modified. Also, application specific interfaces to the application are making it difficult to create inter-operable and extensible applications. Further, the application specific management software is difficult to reuse in diverse applications.
Industry spends hundreds of billions annually on business application software development and maintenance (systems such as payroll or inventory control for instance). The average new application in major corporations comprises over 2,000,000 lines of application program code, and takes over two years to develop. The state of the art software development methodologies are all variations on: get a good set of requirements for the problem to be solved, design the data model and the application code to operate on it, then program and test until the requirements have been addressed. The best approaches are noted for eliciting more of the requirements up front and/or losing less of the problem definition in the many translations from requirements to design and design to code.
There have been prior attempts to reduce the complexity of this process. One of the most popular and successful has been to generate the application code from a complete model of the solution. Another is to parameterize parts of the system. Still another is to treat lines of code like data. These prior efforts are discussed briefly in turn.
Computer Aided Software Engineering (CASE) tools assist in modeling project functions, information flows, data entities and other information regarding the proposed system requirements. CASE tools and many other tools approach the software development problem by creating a model of the problem to be solved and then generating the code to solve it. While this does an adequate job of addressing the problem, it does not do an optimal job. The CASE tool requires the practitioner to define the problem in a very specific fashion, which then goes through a specific translation to a specific target architecture. In many cases they form a pictorial representation of the control structures described below under programming. While this solution offers some advantages, it still relies on implementing the application as coded program logic. More importantly, once such a system is constructed, it is basically a monolith, it is the same application for all users and any proposed changes must go through the CASE generation process again.
The second prior approach is parametric construction or execution. Parametric approaches offer good performance in narrowly defined application domains where the data characteristics and application behavior are well understood and characterized. For example, parametric CAD systems take the approach that key variables can be substituted for parts of a mechanical design and generate the rest. The inventors of the present invention are aware of a prior system that accepted parametric adjustment of some standard program designs as a way to generate code rapidly. In referring to the programming analysis above, the parametric approach is essentially a process of selecting at precompile time which of a predefined set of already coded application code segments will be executed.
With the popularity of Smalltalk, and more recently Java.TM. (a trademark or registered trademark of Sun Microsystems, Inc. in the United States and other countries.), has been a resurgence in interpreted languages, and with them a notion that the code can be stored and treated as data. In an interpreted language each line of code can be stored as data (e.g., bytecodes in Java) and invoked at run time. An interpreter receives the data and converts it to machine executable code. At one level the code is like data, it is stored in a database and does not need to be part of a compiled and linked executable. But in every other regard it still procedural code, subject to all the flow of control, and need for testing as any other program code. Indeed the testing need is even greater as there is no way to exhaustively demonstrate the correctness of a program where flow of control logic can be changed at any time.
Conventional applications, even object oriented applications, are deployed as procedural code. A typical application comprises a plurality of modules that each perform a specified set of tasks. These modules are linked and compiled to provide executable code that implements the application. At runtime, the executable code is loaded into machine memory and provides the applications features and behavior by executing the specified set of tasks in the machine. Program compilation occurs before the application is deployed such that the application cannot be fundamentally changed at runtime. Interpreted language applications differ from conventional applications in that they are stored as a collection of "byte-codes" that are interpreted at runtime to generate the procedural executable. In a sense, these applications postpone the compilation process (i.e., the process that translates data into procedural code) until runtime, but do not otherwise change conventional implementation of software applications.
As software complexity increases, verification of the functionality (i.e., the features and behavior of the software) has become problematic. When an application comprises thousands or millions of lines of code it becomes impracticable to test or simulate every possible failure mode. Until applications are actually used in their intended environment, many problems or limitations remain unknown. This increases the cost of maintenance and support for the application. In many mission critical applications (e.g., medical, financial, and security) it is vital that an application be implemented only after verification is complete. What is needed is a reliable system that can adapt to provide new functionality without the delays and cost imposed by software verification.
The last several decades have been characterized by rapid change in computing hardware and an increase in operating system complexity to provide new functionality and exploit features of improved hardware. Consequently, software applications written to cooperate closely with the OS or hardware have extremely short product life cycles. Moreover, hardware and OS manufacturers often limit the improvements that are made so that their hardware remains inter-operable with a sizable base of installed software applications. Hence, the inability described above of software applications to evolve results in a chilling effect on the entire computer industry.